casting 就是資料型態之間的轉換。
例如把 A type 轉換成 B type。 但是這中間會發生一些問題。
每個變數就像是一個水桶一樣,擁有不同的容量可以存取資訊,而這些資訊就像是水一樣,可以被裝進水桶裡面,但是在不同的水桶裡面會以不一樣的方式呈現。
就拿 int 做舉例,他的容量是 4 個 byte,short 只有 2 個 byte,long 也有 4 個 byte。
每個變數,就像是具有不一樣的形狀水桶,
例如:
int 和 float 可以存入的資訊大小是一模一樣的,但是他們裝入的資訊卻是不一樣的。
int 只有裝入正負號、整數的部分;
但是 float 卻可以裝入正負號、整數、還有小數的部分。
所以我會把每個變數想像成不同大小的水桶,例如 int 是圓柱形、float 是長方形(隨便假設的xd)。
這個部分,可以很簡單的來說就是
把容量比較小的變數,轉換成容量比較大的變數。
原本有兩個水瓶,一個現在是裝滿水的、另外一個是空的,裝滿水的那個水瓶的容量是 500 mL;空的那個水瓶容量是 1000 mL。所以直接把裝滿水的水瓶中的水,直接倒入空水瓶,一滴都不會漏出來。
所以在 implicit casting 的情況,資料的值以及精確度都不會流失或改變。
與 Implicit casting 的情形相反,explicit casting 就是把容量比較大的變數,轉換成容量比較小的變數。
而這種轉換的問題在於,大的變數轉換成小的變數時,會發生 overflow 的情形。
簡單來說,就是跟上面的情形一樣,有一個裝滿水的水瓶,但是這次容量比較大,是1000mL;而另外一個空的水瓶只有 500 mL。如果把水全部倒進空的水瓶的話,水就會滿出來,導致水的流失。
但是在 explicit casting 的情況下卻會因為 overflow等原因產生資訊值或是精確度的改變。
在進行 explicit casting 的時候,需要告知 compiler 或是未來可能會看到這段 code 的人,你要進行 explicit casting。
那, explicit casting 要怎麼寫咧?
(X) : int number = 5.6
才不是這樣寫。
(O) : int number = static_cast<int>(5.6);
這樣才對嘛!
所以可以看到這種轉換的公式:
static_cast<*type*>(*expression*);
註: 當 float 或是 double 轉換成 int 的時候,他的小數部分會被截斷,無條件捨去!
那為什麼我們需要自己做 casting 呢?何不交給電腦自己處理?
這是因為在explicit casting 中,我們可以明確的指出我們需要做出何種 casting (ex: float → int),且因為當你是自己寫的時候,compiler 才不會因為自己判斷而出現錯誤,你又抓不出問題在哪裡。
下面就來個 char 跟 int 產生 overflow 的例子:
#include<iostream>
using namespace std;
int main(){
char c = 254;
int a = 10;
cout << c + a;
}
這段程式的結果會跑出 8
你可能會覺得很奇怪,但是要注意
char 的最大值只到 127欸,他早就已經 overflow 了,所以就會發生出現 8 的情形啦。
Casting 就像是我現在的人生一樣
要從不同領域轉換到另一個領域
所以我應該是需要 explicit casting 的 ☹️